package org.zjt.register;

import org.apache.zookeeper.data.Stat;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.zjt.annotation.RpcService;
import org.zjt.config.ApplicationProperties;
import org.zjt.config.RegisterConfig;
import org.zjt.config.ZKConnectCenter;
import org.zjt.register.service.IRegisterService;
import org.zjt.register.service.impl.RegisterServiceImpl;
import org.zjt.domain.RegisteNodeData;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;

/**
 * Created by Administrator on 2017/4/13.
 */
//@Component
@SuppressWarnings("all")
public class ZKRouteMonitor implements ApplicationContextAware {

    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    private ApplicationProperties applicationProperties;

    @Autowired
    private ZKConnectCenter zkConnectCenter;

    static final String ZK_SEPARATOR = "/";

    @PostConstruct
    void updateRouteInfo() throws Exception {
        IRegisterService registerService = new RegisterServiceImpl();
        Map<String, Object> classes = applicationContext.getBeansWithAnnotation(RpcService.class);
        for (Map.Entry<String, Object> entry : classes.entrySet()) {
            Object o = applicationContext.getBean(entry.getKey());
            for (Class var : o.getClass().getInterfaces())
                applicationProperties.getRegisterConfig().REGISTER_BEAN_MAP.put(var.getName(),
                        new RegisteNodeData(applicationProperties.getNettyConfig().getIp(),
                                applicationProperties.getNettyConfig().getPort(), o.getClass().getName()));
        }
        //log.info(JSONObject.toJSONString(classes));
        //注册
        registerService.registerRouteInfo(applicationProperties.getRegisterConfig().REGISTER_BEAN_MAP, applicationProperties.getServerName(), applicationProperties.getPort(), zkConnectCenter, RegisterConfig.RPC_PARENT_PATH);
        registerService.loadRouteInfo(zkConnectCenter, applicationProperties.getRegisterConfig(), RegisterConfig.RPC_PARENT_PATH);
        registerService.watchRouteInfo(RegisterConfig.RPC_PARENT_PATH, zkConnectCenter, applicationProperties.getRegisterConfig());
    }


    @PreDestroy
    public void cancelProvider() throws Exception {
        if (applicationProperties.getRegisterConfig().REGISTER_BEAN_MAP.isEmpty())
            return;
        /** data.put(RPCFacade.class.getName(),new RegisteNodeData("localhost",8070, RpcImpl.class.getName())); */
        for (Map.Entry entry : applicationProperties.getRegisterConfig().REGISTER_BEAN_MAP.entrySet()) {
            Stat stat = zkConnectCenter.getZKConnect().checkExists().forPath(
                    RegisterConfig.RPC_PARENT_PATH + ZK_SEPARATOR + entry.getKey() + ZK_SEPARATOR + applicationProperties.getServerName() + ":" + applicationProperties.getPort());
            if (stat != null)
                zkConnectCenter.getZKConnect().delete().deletingChildrenIfNeeded().forPath(
                        RegisterConfig.RPC_PARENT_PATH + ZK_SEPARATOR + entry.getKey() + ZK_SEPARATOR + applicationProperties.getServerName() + ":" + applicationProperties.getPort());
        }
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
